/**
 *	Main entry into the app
**/

"use strict"

/*
require("Game/Game.GUI.js")
require("MouseEvents.js")
require("Game/GameLogic.validator.js")
require("Game/GameLogic.winChecker.js")
require("API.js")
*/

var Game = {
	
	_isInit: false,
	
	init: function() {
		if (this._isInit)  return
		
		var c = this.c = document.getElementById("GameBoard")
		var ctx = this.ctx = c.getContext("2d")
		
		c.width = c.offsetWidth												//resize the canvas itself, or it will stretch
		c.height = c.offsetHeight
		
		ctx.fillStyle = "black"
		ctx.fillRect(0, 0, c.offsetWidth, c.offsetHeight)
		
		//game info prototypes
		this.game = { }
		this.localPlayer = { }
		
		
		MouseEvents.createMouseEvents(c, this.game, this.localPlayer)		//create mouse events on the canvas
		MouseEvents.createTimerEvents(this.game, this.localPlayer)			//create timer events for querying the API
		
		this._isInit = true
	},
	
	//retrieves game info from the server and sets up a new game
	setUpGame: function(newGameInfo) {
		//alert(JSON.stringify(newGameInfo))
		
		// pick up the playerName from Main
		var playerName = Main.clientInfo.user
				
		// since we have passed the game object around a lot we can't just delete it, so lets zero it
		for (var i in this.game) {
			delete this.game[i]
		}
		
		// now apply values which came from the server
		for (var i in newGameInfo) {
			this.game[i] = newGameInfo[i]
		}
		
		// zero localPlayer
		for (var i in this.localPlayer) {
			delete this.localPlayer[i]
		}
		
		// set local player info
		this.localPlayer.name = playerName
		this.localPlayer.num = ( this.game.players[0] == playerName ? 1 : 2 )
		console.log(playerName)
		console.log(this.game.players)
		
		// set up the UI
		Controllers.GamePage.setup(this.game)
		
		// show the screen
		this.draw()
	},
	
	//draw screen
	draw: function() {		
		var ctx = this.ctx, c = this.c
		
		//cls
		ctx.fillStyle = "black"
		ctx.fillRect(0, 0, c.offsetWidth, c.offsetHeight)
		
		//if game board info does not exists yet, give up on draw
		if (!this.game.board)  return
		
		
		//guide lines
		var w = this.game.board.w,
			h = this.game.board.h,
			lw = Math.round( c.offsetWidth / w ),
			lh = Math.round( c.offsetHeight / h )
		
		ctx.fillStyle = "white"
		
		for (var i=1; i<h; i++) {
			ctx.fillRect(0, lh*i, c.offsetWidth, 1)
		}
		for (var i=1; i<w; i++) {
			ctx.fillRect(lw*i, 0, 1, c.offsetHeight)
		}
		
		//markers
		var s = this.game.state
		for (var i=0; i<h; i++) {
			for (var j=0; j<w; j++) {
				if ( s[i][j] != 0 ) {
					this._drawMarker( j, i, lw, lh, s[i][j] )
				}
			}
		}
		
		//GUI
		Controllers.GamePage.playerTurn(this.game.turn)
	},
	
	//draws a single marker
	_drawMarker: function(x, y, mwidth, mheight, marker) {
		var ctx = this.ctx,
			offsetX = mwidth * x + Math.floor(mwidth/2),				//useful offsets
			offsetY = mheight * y + Math.floor(mheight/2),
			msize = ( mwidth < mheight ? mwidth : mheight )				//use smallest size as dominant
		
		ctx.strokeStyle = "white"
		ctx.beginPath()
			
		if (marker === 1) {
			//draw a circle. use smallest side as the radius
			ctx.arc(offsetX, offsetY, Math.round(msize*0.4), 0, Math.PI*2)
		} else {
			//draw a cross
			var sizetmp = msize * 0.4
			ctx.moveTo(offsetX - sizetmp, offsetY - sizetmp)
			ctx.lineTo(offsetX + sizetmp, offsetY + sizetmp)
			ctx.moveTo(offsetX - sizetmp, offsetY + sizetmp)
			ctx.lineTo(offsetX + sizetmp, offsetY - sizetmp)
		}
		
		ctx.closePath()
		ctx.stroke()
	},
	
	
	// useful helper function
	_cloneMove: function(move) {
		var m = { }
		for (var i in move) {
			m[i] = move[i]
		}
		return m
	},
	
	// makes a move on the client or server!
	makeMove: function(move) {
		//console.log(JSON.stringify(move))
		
		var m = this._cloneMove(move),									//make sure the validator doesn't alter the move
			result = GameLogic.validator.validate( this.game, m )  		//check if move is valid
		
		if (result.success === false) {
			Controllers.GamePage.userLog(result.message)				//report to user if invalid
			return
		}
		
		// make the move
		if ( this.game.moveType === "add" ) {
			this.game.state[move.y][move.x] = this.game.turn
		} else if ( this.game.moveType === "move" ) {
			this.game.state[move.y2][move.x2] = this.game.state[move.y][move.x]
			this.game.state[move.y][move.x] = 0
		}
		
		this.game.turn = ( this.game.turn == 1 ? 2 : 1 )				//update current turn
		this.game.turnCount++											//increment number of turns taken this game
		this.game.winner = GameLogic.winChecker.check( this.game )		//check if game has been won
		
		this.draw()														//redraw board
		
		// send the move, if the move was set to be sent online
		if (move.online) {
			m = this._cloneMove(move)
			delete m.online
			m.gameId = this.game.gameId
			m.turnCount = this.game.turnCount
			
			API.sendMove(m)
		}
		
		// could alert the winstate possibly?
		if (this.game.winner !== 0) {
			//note: also in MouseEvents (and one other?)
			if (this.game.winner === -1) {
				Controllers.GamePage.userLog( "The game ended in a draw!" )
			} else {
				var winner = this.game.players[this.game.winner - 1]
				Controllers.GamePage.userLog( "The game was won by: " + winner + "!")
			}
		}
	}
		
}